#ifndef _CENTER_BATTLE_MAMANAGER_H_
#define _CENTER_BATTLE_MAMANAGER_H_

#include "Common.h"
#include "Resource.h"
#include "ResourceManager.h"
#include "Singleton.h"
#include "String.h"
#include "Database/Field.h"
#include "DataManager.h"
#include "CenterBattleLogManager.h"

#include "Threading/Mutex.h"

#define DB_NAME_CENTERBATTLE		"center_battle"

class  Database;
class  CharPtr;
class  ChannelPtr;
class  ItemPtr;
class  WorldPacket;
class  WSSocketPtr;

typedef struct center_battle_tag_
{
	uint32 cb_id;			//中心组局ID
	uint32 group_id;		//服务器组ID
	uint32 gz_id;			//要创建牌桌的分区ID
	uint32 game_id;			//游戏ID
	uint32 status;			//状态(0 初始 1 申请 2 正在创建 3 运行中 255 删除)
	uint32 pid;				//房主pid
	uint64 club_id;			//俱乐部ID
	uint64 club_room_id;	//俱乐部房间ID
	uint32 reg_from;		//注册来源
	String openid;			//房主openid
	String battle_name;		//房间名称
	String name;			//房主名称
	String head;			//房主头像
	
	uint32 istrack;			//是否追踪
	uint32 curr_loop;		//当前局数
	uint32 limit_loop;		//限制局数
	uint32 limit_time;		//限制时间（s）
	uint32 top_times;		// 限制倍数翻数
	uint32 coins_model;		//游戏输赢货币类型
	uint32 init_coins;		//初始带入货币数量
	uint32 limit_coins;		//进入限制铜钱
	uint32 base_coins;		//底分
	uint32 fan_coins;		//翻分（特定游戏）
	uint32 think_time;		//考虑时间
	uint32 timeout;			//超时时间
	uint32 pause;			//暂停
	uint32 start_time;		//组局开始时间
	uint32 max_player;		//最大玩家数量
	uint32 channel_id;		//牌桌ID
	uint32 mode;			//游戏模式
	uint32 pay_mode;		//付费模式（1 房主 2 AA制）
	String join_code;		//进牌桌验证码
	String create_time;		//组局创建时间
	String end_time;		//组局结束时间
	String player;			//玩家列表
	String black_list;		//黑名单列表
	
	uint32 data1;			
	uint32 data2;			
	int32 data3;	
	int32 data4;
	int32 data5;
	int32 data6;
	int32 data7;
	int32 data8;
	String sdata1;				
	String sdata2;
	String sdata3;
	String sdata4;
	String sdata5;
	String sdata6;
	String sdata7;
	String sdata8;
	
	uint32 update_key;		//数字更新锁
	
	center_battle_tag_()
	{
		Init();
	}
	
	void Init()
	{
		cb_id = 0;
		group_id = 0;
		gz_id = 0;
		game_id = 0;
		status = 0;
		pid = 0;
		club_id = 0;
		club_room_id = 0;
		reg_from = 0;
		openid = "";
		battle_name = "";
		name = "";
		head = "";
		
		istrack = 0;
		curr_loop = 0;
		limit_loop = 0;
		limit_time = 0;
		top_times = 0;
		coins_model = 0;
		init_coins = 0;
		limit_coins = 0;
		base_coins = 0;
		fan_coins = 0;
		think_time = 0;
		timeout = 0;
		pause = 0;
		start_time = 0;
		max_player = 0;
		channel_id = 0;
		mode = 0;
		pay_mode = 0;
		join_code = "";
		create_time = "";
		end_time = "";
		player = "";
		black_list = "";
		
		data1 = 0;
		data2 = 0;
		data3 = 0;
		data4 = 0;
		data5 = 0;
		data6 = 0;
		data7 = 0;
		data8 = 0;
		sdata1 = "";
		sdata2 = "";
		sdata3 = "";
		sdata4 = "";
		sdata5 = "";
		sdata6 = "";
		sdata7 = "";
		sdata8 = "";
		
		update_key = 0;
	}
	
}CenterBattle;

struct stPlayerCreateCenterBattle
{
	uint32 cb_id;		// 组局ID
	uint32 pid;			// 房主PID
	uint32 gz_id;		// 分区ID
	uint32 game_id;		// 游戏ID
	uint32 base_coins;	// 底分
	uint32 fan_coins;	// 翻分
	uint32 mode;		// 棋牌圈模式
	
	uint32 istrack;		// 是否更新
	uint32 limit_loop;	// 限制局数
	uint32 limit_time;	// 限制时间
	uint32 top_times;	// 封顶
	
	uint32 coins_model;	// 输赢游戏货币类型
	uint32 init_coins;	// 初始带入游戏币数量
	
	uint32 think_time;	// 考虑时间
	uint32 timeout;		// 超时时间
	
	String name;		// 房主名称
	String battle_name;	// 房间名称
	String extra_data;	// 游戏玩法设定
	
	stPlayerCreateCenterBattle()
	{
		Init();
	}
	
	void Init()
	{
		cb_id = 0;
		pid = 0;
		gz_id = 0;
		game_id = 0;
		base_coins = 0;
		fan_coins = 0;
		mode = 0;
		istrack = 0;
		limit_loop = 0;
		limit_time = 0;
		top_times = 0;
		coins_model = 0;
		init_coins = 0;
		think_time = 0;
		timeout = 0;
		
		name = "";
		battle_name = "";
		extra_data = "";
	}
	
};

struct stCenterBattlePlayerInfo
{
	uint32 pid;
	uint32 cid;
	int winLose;
	uint32 player_count;
	uint32 player_status;	// 角色状态（空闲 游戏中 离开 结束游戏）
	
	String name;
	String desc;
	
	stCenterBattlePlayerInfo()
	{
		Init();
	}
	
	void Init()
	{
		pid = 0;
		cid = 0;
		winLose = 0;
		player_count = 0;
		player_status = 0;
		
		name = "";
		desc = "";
	}
	
};

enum enCenterBattleStatus 
{
	enBattleStatus_Default = 0,		// 默认状态
	enBattleStatus_Require = 1,		// 申请创建
	enBattleStatus_Created = 2,		// 创建完成
	enBattleStatus_Process = 3,		// 运行中
	enBattleStatus_playing = 4,		// 游戏中
	enBattleStatus_Finish = 5,		// 组局结束（正常结束）
	enBattleStatus_Delete = 255,	// 删除组局
};

enum enCenterBattlePauseOperator
{
	enCenterBattlePauseStatus_Pause = 1,		// 暂停
	enCenterBattlePauseStatus_CancelPause = 2,	// 取消暂停
	enCenterBattlePauseStatus_KickPlayer = 3,	// 踢出玩家
	enCenterBattlePauseStatus_Dissolve = 4,		// 解散牌桌
};

// 协议返回结果
enum enProtocolsResult
{
	enResult_Failed = 0,		// 失败
	enResult_Sucess = 1,		// 成功
	
	// 申请组局相关
	enCreateBattle_OverLimitCount = 2,		// 创建牌桌超过限制局数
	enCreateBattle_NoLimit = 3,				// 局数和时间限制不能同时为0
	enCreateBattle_JustOneLimit = 4,		// 最多只能选择一种限制条件
	enCreateBattle_NeedMoreLoop = 5,		// 设置轮数低于最低限制
	enCreateBattle_NeedMoreTime = 6,		// 设置时间低于最低限制
	enCreateBattle_ErrorGzid = 7,			// 无效的游戏ID
	enCreateBattle_CreateDataField = 8,		// 创建数据失败
	enCreateBattle_ErrorBaseCoins = 9,		// 错误的底分
	enCreateBattle_MoreCoins = 10,			// 低于最低带入货币数量
	enCreateBattle_ErrorThinkTime = 11,		// 低于最低考虑时间
	enCreateBattle_MoreTimeoutTime = 12,	// 低于最低超时时间
	enCreateBattle_GoldTicketNeed = 13,		// 开局费不足（收到此结果可以弹出充值页面）
	enCreateBattle_ErrorLoop = 14,			// 无效的局数
	enCreateBattle_NoThisMode = 15,			// 无效的游戏玩法
	enCreateBattle_NoClubID = 16,			// 无效的俱乐部ID
	enCreateBattle_ClubQuanXian = 17,		// 玩家俱乐部权限不足
	enCreateBattle_ErrorPid = 100,			// 无效的玩家PID
	enCreateBattle_EmprtParmas = 101,		// 创建组局参数不能为空
	enCreateBattle_NoUser = 102,			// 该PID玩家还未创建用户
	enCreateBattle_NoBank = 103,			// 该PID玩家没有银行数据
	enCreateBattle_NoChar = 104,			// 该PID玩家没有角色数据
	enCreateBattle_NoGzidInfo = 105,		// 您至少需要创建一次该玩法的牌局
	enCreateBattle_InOtherGame = 106,		// 您正在其他游戏中进行游戏
	
	
	// 创建游戏牌桌相关
	enCreateGameBattle_NoThisCenterBattle = 2,	// 没有此组局信息
	enCreateGameBattle_ErrorPID = 3,			// PID不对
	enCreateGameBattle_ErrorStatus = 4,			// 错误的状态
	enCreateGameBattle_CreateFailed = 5,		// 创建牌桌失败
	enCreateGameBattle_GoldTicketNeed = 6,		// 开局费不足（收到此结果可以弹出充值页面）
	enCreateGameBattle_DataUpdateFailed = 7,	// 数据更新失败
	
	// 暂停牌桌相关
	enPauseBattle_NoThisCenterBattle = 2,		// 无此组局信息
	enPauseBattle_NotProcess 		= 3,		// 组局未在运行中
	enPauseBattle_ChannelNull 		= 4,		// 未找到创建的牌桌
	enPauseBattle_SameOperator 		= 5,		// 重复操作
	enPauseBattle_ErrorPID 			= 6,		// 错误的PID
	enKickPlayer_CharNotExist = 7,				// 要踢的角色不存在
	enKickPlayer_KickFailed = 8,				// 踢人失败
	enKickPlayer_DataUpdateFailed = 9,			// 数据更新失败
	enKickPlayer_DissolveFailed = 10,			// 解散牌桌失败
	
	// 踢人结果
	enKickPlayer_ErrorID = 2,					// 错误的组局ID
	enKickPlayer_NotRoomOwner = 3,				// 你不是房主
	enKickPlayer_BattleNotRunning = 4,			// 此组局未在进行中
	enKickPlayer_ChannelNull = 5,				// 牌桌不存在或者已经结束
	
	// 进牌桌结果
	enJoinChannel_ReturnServerID = 2,			// 返回游戏服务器ID
	enJoinChannel_NoThisBattle = 3,				// 没有此组局
	enJoinChannel_ErrorStatus = 4,				// 错误状态
	enJoinChannel_ChannelNull = 5,				// 牌桌不存在或者已经结束
	enJoinChannel_PlayerFull = 6,				// 牌桌已满
	enJoinChannel_AlreadyJoin = 7,				// 重复进入
	enJoinChannel_InOtherChannel = 8,			// 已经在其他牌桌
	enJoinChannel_DataUpdateFailed = 9,			// 数据更新失败
	enJoinChannel_ChannelRunning = 10,			// 牌局进行中
	enJoinChannel_HasBeenKicked = 11,			// 被踢出的玩家无法再次加入
	enJoinChannel_Playing = 12,					// 游戏开始无法进入
	enJoinChannel_NeedRoomCards = 13,			// 房卡不足（AA制度）
	enJoinChannel_GameOver = 14,				// 组局已结束
	enJoinChannel_ErrorPasswd = 15,				// 密码错误
	enJoinChannel_SeatFull = 16,				// 座位已被占
};

enum enCenterBattlePlayerStatus
{
	enCenterBattlePlayerStatus_None = 0,				// 无效
	enCenterBattlePlayerStatus_Free = 1,				// 空闲
	enCenterBattlePlayerStatus_Playing = 2,				// 游戏中
	enCenterBattlePlayerStatus_LeaveWithScore = 3,		// 离开（成绩在牌桌）
	enCenterBattlePlayerStatus_LeaveWithNoScore = 4,	// 离开（没有成绩）
	enCenterBattlePlayerStatus_GameOver = 255,			// 完成游戏
};

enum enPayMode
{
	enPayMode_FangZhu = 1,			// 房主
	enPayMode_AAPay = 2,			// AA制
	enPayMode_LoopPay = 3,			// 金币场
};

#define WGS_CENTERBATTLE_MUTEX_NAME centerbattle_mutex
#define WGS_CENTERBATTLE_MUTEX mutable boost::mutex WGS_CENTERBATTLE_MUTEX_NAME;
#define WGS_CENTERBATTLE_LOCK		boost::lock_guard<boost::mutex> wgsCenterBattleMutexLock(WGS_CENTERBATTLE_MUTEX_NAME);

//-------------------------组局信息-----------------------
class  SERVER_DECL CenterBattleManager:public Singleton<CenterBattleManager>
{
public:
	CenterBattleManager();
	
	WGS_CENTERBATTLE_MUTEX
	/**
	 * @创建时间 2016-07-13
	 * @创建人 Roach
	 * @函数作用 添加一条CenterBattle记录
	 * @参数
	 * 	@cb	CenterBattle
	 */
	bool AddCenterBattle(CenterBattle & cb);
	
	/**
	 * @创建时间 2016-07-13
	 * @创建人 Roach
	 * @函数作用 更新friendrecord数据
	 * @参数
	 * 	@cb CenterBattle
	 */
	bool UpdateCenterBattle(const CenterBattle & cb, uint32 update_key = 0);
	
	/**
	 * @创建时间 2016-07-13
	 * @创建人 Roach
	 * @函数作用 更新friendrecord数据
	 * @参数
	 * 	@cfr_id	
	 *	@fields	字段键值对,格式：fields["key1"] = 1; fields["key2"] = 2;...
	 */
	bool UpdateCenterBattle(Fields * fields, const char * QueryString, ...);
	bool UpdateCenterBattle(const uint32 &cf_id, const uint32 & update_key, Fields * fields);
	
	/**
	 * @创建时间 2016-07-13
	 * @创建人 Roach
	 * @函数作用 根据PD_ID获取一条PD数据
	 * @参数
	 *  @cfr_id CenterBattle id
	 * 	@cb		CenterGameFriend对象
	 */
	bool GetCenterBattle(const uint32 &cb_id, CenterBattle * cb);
	
	/**
	 * @创建时间 2016-07-13
	 * @创建人 Roach
	 * @函数作用 获取记录列表
	 * @参数
	 * 	@lstData	CenterFriendRecord对象列表
	 *  @query 查询语句条件
	 */
	uint32 GetCenterBattleList(std::list<CenterBattle> * lstData, const char * query,...);

public:
	void Update();
	
	//========================逻辑操作相关===================================
	// 玩家申请创建组局
	bool PlayerCreateCenterBattle(CharPtr & pChr, String strData);
	// 机器人帮玩家创建组局
	uint8 RobotCreateCenterBattle(String strData, String & strExtraData, String & strShareInfo);
	// 系统创建组局
	uint8 SystemCreateCenterBattle(String strData);
	// 创建游戏牌桌
	bool CreateGameChannel(WSSocketPtr & socket, const uint32 & pid, const uint32 & cb_id, const uint32 & gz_id, const uint32 & update_key = 0);
	// 机器人帮玩家创建组局
	uint8 RobotCreateGameChannel(String strParmars);
	// 牌桌创建更新组局信息（更新状态，牌桌ID，进入牌桌的兑换码）
	bool UpdateCenterBattleChannelInfo(CharPtr & pChr, const uint32 & cb_id, ChannelPtr & pChannel);
	// 发送某个玩家组局信息列表
	void SendPlayerCenterBattleListInfo(CharPtr & pChr);
	// 发送某个俱乐部组局信息列表
	void SendClubCenterBattleListInfo(CharPtr & pChr, const uint64 & club_id);
	// 发送某个组局信息
	void SendPlayerCenterBattleInfo(CharPtr & pChr, const uint32 & cb_id);
	// 暂停/继续组局
	bool OperatorBattle(WSSocketPtr socket, 
						const uint32 & platform_id, 
						const uint32 & cb_id, 
						const uint8 & mode, 
						const uint32 & data, 
						const uint32 & update_key = 0);
	// 踢人 pChr：房主 cb_id：组局ID kick_charid：要踢的角色ID
	bool KickPlayer(WSSocketPtr socket, const uint32 & platform_id, const uint32 & cb_id, const uint32 & kick_charid);
	// 进牌桌
	bool JoinCenterBattle(CharPtr & pChr, String join_code);
	// 玩家加入组局列表数据
	bool AddPlayerDataToCenterBattle(CharPtr & pChr, CenterBattle & cb, const uint8 & pos = 255);
	// 创建或者加入组局
	bool CreateOrJoinCenterBattle(CharPtr & pChr, String join_params);
	// 组局换桌（有现成的就加入，没有就创建一个）
	bool ChangeJoinCenterBattle(CharPtr & pChr);
	// 系统创建组局
	bool CreateCenterBattleBySystem(String params);
	// 获取斗地主公共组局列表
	void GetDDZPublicBattleList(CharPtr & pChr, String params);
	// 获取俱乐部选座房间组局列表
	void GetClubChooseSeatBattleList(CharPtr & pChr, String params);
	// 牌局上锁 passwd有值表示上锁，没值表示解锁
	bool SetBattlePasswd(const uint32 & cb_id, String & passwd);
	
	// 获得牌桌玩家信息 cb_id 组局ID  char_id 要请求数据的角色ID
	stCenterBattlePlayerInfo GetPlayerInfo(const uint32 & cb_id, const uint32 & char_id);
		
	// 更新牌桌玩家信息（可以在CenterBattleLogManager::AddCenterBattleLoopTotalLog函数中调用更新的逻辑）
	bool UpdatePlayersInfo(const uint32 & cb_id, std::vector<CenterBattlePlayerWinLose> player_winLose, String strExtraData);
	
	// 玩家离开组局牌桌
	bool PlayerLeaveChannel(const uint32 & cb_id, const uint32 & char_id);
	
	// 开始新的一局
	bool StartNewLoop(const uint32 & cb_id, std::vector<uint32> del_chars, std::vector<uint32> playing_chars);
	
	// 组局结束 nExitType 是否正常结束（0 表示正常 1 ）
	bool CenterBattleComplate(const uint32 & cb_id, const uint8 nExitType = 0);
	
	// 设置组局牌桌为运行中等待玩家开始
	void SetCentetBattleProcess(const uint32 & cb_id);
	
	// 更新当前局数
	bool UpdateCenterBattleCurrloop(const uint32 & cb_id, const uint32 & loop);
	
	// AA制扣除玩家房卡
	bool ReducePlayerAADiamand(const uint32 & cb_id, std::map<uint32, uint32> vPCid, const uint32 & reduce_num);
	
	// 获取某游戏公共房列表
	std::list<CenterBattle> GetPublicCenterBattleList(const uint32 & agent_id, const uint32 & game_id);
	//========================逻辑操作相关===================================
	
	//========================获取服务器信息=================================
	String PushMessageToUser(const uint32 & uid, String data);
	// 获取组局房间ID
	String GetCenterBattleJoinCode(const uint32 & cb_id);
	
	// 机器人进入组局
	void RobotJoinCenterBattle(CharPtr & pChr, const uint32 & cb_id, const uint32 & pos);
	
	//========================获取服务器信息=================================
	
public:
	// 上一次更新时间
	uint32 m_nPreUpdateTimer;
	// 内存管理的组局列表
	std::map<uint32, std::map<uint32, std::vector<CenterBattle> > > m_mapCenterBattle;
	// 操作换桌时间map
	std::map<uint32, uint32> m_mapChangeTableTimer;
};

#define	 sCenterBattleMgr		 CenterBattleManager::getSingleton()


//====================================玩家组局信息=================================
typedef struct center_battle_user_tag_
{
	uint32 serial;			// 玩家组局信息序列号
	uint8 status;			// 状态（0 无效 1 空闲 2 牌局中  255 结束）
	uint32 cb_id;			// 组局ID
	uint32 platform_id;		// 玩家PID
	uint32 char_id;			// 角色ID
	String name;			// 玩家昵称
	String head;			// 玩家头像
	uint8 is_room_owner;	// 玩家是否房主
	uint8 is_in_blacklist;	// 是否在黑名单中
	uint32 loop;			// 游戏局数
	int32 curr_score;		// 当前积分
	
	String create_time;		// 创建时间
	String end_time;		// 结束时间
	
	uint32 data1;			// 无符号整形1
	uint32 data2;			// 无符号整形2
	uint32 data3;			// 无符号整形3
	uint32 data4;			// 无符号整形4
	
	center_battle_user_tag_()
	{
		Init();
	}
	
	void Init()
	{
		serial = 0;
		status = 0;
		cb_id = 0;
		platform_id = 0;
		char_id = 0;
		name = "";
		head = "";
		is_room_owner = 0;
		is_in_blacklist = 0;
		loop = 0;
		curr_score = 0;
		
		create_time = "";
		end_time = "";
		
		data1 = 0;
		data2 = 0;
		data3 = 0;
		data4 = 0;
	}
	
}CenterBattleUser;

struct stUpdatePlayerInfo
{
	uint32 pid;
	uint32 cid;
	int32 winlose;
	uint32 play_count;
	uint32 player_status;
	
	String name;
	String head;
	
	stUpdatePlayerInfo()
	{
		Init();
	}
	
	void Init()
	{
		pid = 0;
		cid = 0;
		winlose = 0;
		play_count = 0;
		player_status = 0;
		
		name = "";
		head = "";
	}
	
};

enum enCenterBattleUserStatus
{
	enCenterBattleUserStatus_None = 0,			// 默认
	enCenterBattleUserStatus_OutChannel = 1,	// 局外
	enCenterBattleUserStatus_InChannel = 2,		// 局内
	enCenterBattleUserStatus_Playing = 3,		// 游戏中
	enCenterBattleUserStatus_Leave = 4,			// 离开
	enCenterBattleUserStatus_Delete = 255,		// 删除（或者叫结束）
};

#define WGS_CBUSER_MUTEX_NAME cbuser_mutex
#define WGS_CBUSER_MUTEX mutable boost::mutex WGS_CBUSER_MUTEX_NAME;
#define WGS_CBUSER_LOCK		boost::lock_guard<boost::mutex> wgsCBUserMutexLock(WGS_CBUSER_MUTEX_NAME);

#define DB_NAME_CENTERBATTLEUSER	"center_battle_user"

//-------------------------组局信息-----------------------
class  SERVER_DECL CenterBattleUserManager:public Singleton<CenterBattleUserManager>
{
public:
	WGS_CBUSER_MUTEX
	
	// 添加玩家组局信息
	bool AddCenterBattleUser(CenterBattleUser & cbu);
	
	// 更新玩家组局信息
	bool UpdateCenterBattleUser(const CenterBattleUser & cb, uint32 update_key = 0);
	bool UpdateCenterBattleUser(Fields * fields, const char * QueryString, ...);
	bool UpdateCenterBattleUser(const uint32 & serial, Fields * fields);
	
	// 获取玩家组局信息
	bool GetCenterBattleUser(const uint32 & serial, CenterBattleUser * cbu);
	// 获取玩家组局信息列表
	uint32 GetCenterBattleUserList(std::list<CenterBattleUser> * lstData, const char * query,...);
	
	//===============================游戏逻辑部分==================================
	// 获取玩家组局信息
	bool GetCenterBattleUser(const uint32 & cb_id, const uint32 & platform_id, CenterBattleUser * cbu);
	//===============================游戏逻辑部分==================================
	
};


#define	 sCenterBattleUserMgr		 CenterBattleUserManager::getSingleton()

#endif
